package com.gimi.cloud.bbp.task.service.impl;

import com.gimi.cloud.bbp.common.enums.ResponseCodeEnum;
import com.gimi.cloud.bbp.common.exception.MsgException;
import com.gimi.cloud.bbp.common.utils.ReflectUtils;
import com.gimi.cloud.bbp.common.utils.StringUtil;
import com.gimi.cloud.bbp.commonService.mq.enume.QueueEnum;
import com.gimi.cloud.bbp.commonService.mq.service.CommonSenderService;
import com.gimi.cloud.bbp.dao.dao.task.ScheduleJobDao;
import com.gimi.cloud.bbp.dao.myMapper.core.query.QueryParam;
import com.gimi.cloud.bbp.dto.task.ScheduleJobDTO;
import com.gimi.cloud.bbp.entity.task.ScheduleJobEntity;
import com.gimi.cloud.bbp.task.service.ScheduleJobService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 定时任务相关service实现类
 *
 * @author wbj
 * @version 1.0
 * @Description
 * @create 2018-01-08
 **/
@Service
public class ScheduleJobServiceImpl implements ScheduleJobService {
    private ScheduleJobDao scheduleJobDao;
    private CommonSenderService commonSenderService;

    @Autowired
    public ScheduleJobServiceImpl(ScheduleJobDao scheduleJobDao, CommonSenderService commonSenderService) {
        this.scheduleJobDao = scheduleJobDao;
        this.commonSenderService = commonSenderService;
    }

    @Override
    public List<ScheduleJobDTO> queryList(ScheduleJobDTO dto, boolean isPaging) throws Exception {
        if(isPaging){
            PageHelper.startPage(dto.getPageNums(),dto.getPageSizes());
        }
        String sql = "SELECT job.*,det.job_name" +
                " FROM schedule_job job " +
                " LEFT JOIN qrtz_job_details det ON det.JOB_NAME = CONCAT('GIMIII_BBP_TASK_',job.job_id)" +
                " WHERE job.is_delete = 0  and job.job_key like '%'||:jobKey||'%' AND job.job_title LIKE '%'||:jobTitle||'%' ";
        QueryParam queryParam = new QueryParam();
        queryParam.setSql(sql);
        queryParam.setParamObject(dto);
        return scheduleJobDao.selectListDTOBySql(queryParam);
    }

    @Override
    public ScheduleJobDTO save(ScheduleJobDTO dto) throws Exception {
        ScheduleJobEntity job = new ScheduleJobEntity();
        ReflectUtils.copyPropertiesIgnoreNullAndEmptyStr(dto,job);
        job.setJobStatus(0);
        scheduleJobDao.baseInsert(job);
        //默认为暂停
        ReflectUtils.copyPropertiesIgnoreNullAndEmptyStr(job,dto);
        dto.setChangeQueueType("create");
        commonSenderService.sendMessage2Rabbitmq(QueueEnum.TASK,dto);
        return dto;
    }

    @Override
    public ScheduleJobDTO update(ScheduleJobDTO dto) throws Exception {
        ScheduleJobEntity entity = scheduleJobDao.selectByPrimaryKey(dto.getJobId());
        if(null == entity){
            throw new MsgException(ResponseCodeEnum.NO_DATA,"未获取到有效的定时任务!");
        }
        ReflectUtils.copyPropertiesIgnoreNullAndEmptyStr(dto,entity);
        scheduleJobDao.baseUpdateByPrimaryKey(entity);
        ReflectUtils.copyPropertiesIgnoreNullAndEmptyStr(entity,dto);
        dto.setChangeQueueType("update");
        commonSenderService.sendMessage2Rabbitmq(QueueEnum.TASK,dto);
        return dto;
    }

    @Override
    public ScheduleJobDTO load(ScheduleJobDTO dto, Object id) throws Exception {
        ScheduleJobEntity job = scheduleJobDao.queryBy("job_id", id);
        if(null == job){
            return null;
        }
        ScheduleJobDTO scheduleJobDTO = new ScheduleJobDTO();
        ReflectUtils.copyPropertiesIgnoreNullAndEmptyStr(job,scheduleJobDTO);
        return scheduleJobDTO;
    }

    @Override
    public int delete(ScheduleJobDTO dto, Object id, boolean realDel) throws Exception {
        ScheduleJobEntity job = scheduleJobDao.queryBy("job_id", id);
        if(null == job){
            throw new MsgException(ResponseCodeEnum.NO_DATA,"未获取到主键为"+id+"的定时任务，删除失败");
        }
        job.setUid(dto.getUid());
        job.setUname(dto.getUname());
        ReflectUtils.copyPropertiesIgnoreNullAndEmptyStr(job,dto);
        //推送消息删除定时任务
        dto.setChangeQueueType("delete");
        commonSenderService.sendMessage2Rabbitmq(QueueEnum.TASK,dto);
        if(!realDel){
            job.setIsDelete(1);
            return scheduleJobDao.baseUpdateByPrimaryKey(job);
        }
        return scheduleJobDao.deleteByPrimaryKey(id);
    }

    @Override
    public int batchUpdateStatus(ScheduleJobDTO dto, Integer[] jobIds, int status) throws Exception {
        if(null == jobIds || jobIds.length ==0){
            throw new MsgException(ResponseCodeEnum.PARAMETER_ERROR,"未获取到待更新的任务id，修该状态失败");
        }
        String jobIdStr = "";
        for (Integer jobId:jobIds) {
            jobIdStr +=jobId+",";
        }
        jobIdStr = jobIdStr.substring(0,jobIdStr.length() -1);
        String sql = "update schedule_job set job_status = "+status+",update_uid='"+dto.getUid()+"',update_uname='"+dto.getUid()+"',update_time = NOW() where is_delete = 0 and job_id in ("+jobIdStr+")";
        QueryParam queryParam = new QueryParam();
        queryParam.setSql(sql);
        return scheduleJobDao.updateSql(queryParam);
    }

    @Override
    public void runJob(ScheduleJobDTO dto, Integer[] jobIds) throws Exception {
        for(Integer jobId : jobIds){
            dto = load(dto,jobId);
            if(null!= dto){
                dto.setChangeQueueType("run");
                commonSenderService.sendMessage2Rabbitmq(QueueEnum.TASK,dto);
            }
        }
    }

    @Override
    public void pauseJob(ScheduleJobDTO dto, Integer[] jobIds) throws Exception {
        ScheduleJobDTO tempScheduleJob = null;
        for(Integer jobId : jobIds){
            tempScheduleJob = load(dto,jobId);
            if(null!= tempScheduleJob){
                tempScheduleJob.setChangeQueueType("pause");
                commonSenderService.sendMessage2Rabbitmq(QueueEnum.TASK,tempScheduleJob);
            }
        }
        batchUpdateStatus(dto,jobIds, 0);
    }

    @Override
    public void resumeJob(ScheduleJobDTO dto, Integer[] jobIds) throws Exception {
        ScheduleJobDTO tempScheduleJob = null;
        for(Integer jobId : jobIds){
            tempScheduleJob = load(dto,jobId);
            if(null!= tempScheduleJob){
                tempScheduleJob.setChangeQueueType("resume");
                commonSenderService.sendMessage2Rabbitmq(QueueEnum.TASK,tempScheduleJob);
            }
        }
        batchUpdateStatus(dto,jobIds, 1);
    }

    @Override
    public void recreateJob(ScheduleJobDTO dto) throws Exception {
        ScheduleJobDTO scheduleJob = scheduleJobDao.queryScheduleJobByJobId(dto.getJobId());
        if(null == scheduleJob){
            throw new MsgException(ResponseCodeEnum.FAILURE,"未获取到主键为"+dto.getJobId()+"的定时任务，充持久化失败");
        }
        if(StringUtil.isNotBlank(scheduleJob.getJobName())){
            throw new MsgException(ResponseCodeEnum.FAILURE,"该定时任务已持久化，不允许重复持久化");
        }
        scheduleJob.setChangeQueueType("create");
        commonSenderService.sendMessage2Rabbitmq(QueueEnum.TASK,scheduleJob);
    }
}
